home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Libris Britannia 4
/
science library(b).zip
/
science library(b)
/
DJGPP
/
BCCGRX12.ZIP
/
contrib
/
bcc2grx
/
src
/
bccgrx06.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-07-23
|
12KB
|
467 lines
/*
* BCC2GRX - Interfacing Borland based graphics programs to LIBGRX
* Copyright (C) 1993 Hartmut Schirmer
*
* see bccgrx.c for details
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
typedef unsigned char uchar;
typedef signed char schar;
typedef unsigned short ushort;
#include <unistd.h>
#include "bccgrx00.h"
#define FirstUserFont 11
#define LastUserFont (FirstUserFont+9)
#define FirstGrxFont (LastUserFont+1)
#define LastGrxFont (FirstGrxFont+9)
#define NrFonts (LastGrxFont+1)
#define PreSkip 0x080
typedef struct {
unsigned short width;
unsigned short *cmd;
} CharInfo;
static int _height;
static int _multx, _divx, _multy, _divy;
static int _mult[11] = { 1, 3, 2, 3, 1, 4, 5, 2, 5, 3, 4};
static int _div[11] = { 1, 5, 3, 4, 1, 3, 3, 1, 2, 1, 1};
static CharInfo CH[256];
static void *Fonts[NrFonts];
static struct textsettingstype TXT;
static GrTextOption gr_Text;
static void do_init(void)
{
static int Init = FALSE;
int i;
if (Init) return;
for (i=0; i < NrFonts; ++i)
Fonts[i] = NULL;
Fonts[DEFAULT_FONT] = (void *) GrLoadFont("@:pc8x8.fnt");
gr_Text.txo_font = (GrFont *)Fonts[DEFAULT_FONT];
gr_Text.txo_chrtype = GR_BYTE_TEXT;
TXT.font = DEFAULT_FONT;
TXT.direction = HORIZ_DIR;
TXT.charsize = 1;
TXT.horiz = LEFT_TEXT;
TXT.vert = TOP_TEXT;
_multx=_multy =
_divx = _divy = 1;
Init = TRUE;
}
static int _installgrxfont(int start, int stop, char *name)
{
do_init();
while (start < stop && Fonts[start] != NULL) ++start;
if (start >= stop)
return grNoFontMem;
Fonts[start] = (void *) GrLoadFont(name);
if (Fonts[start] == NULL)
return grFontNotFound;
return start;
}
static int SetFont(void *font)
{
uchar *Header;
short *sp;
char *cp, *cd;
int nrch, fstch, lastch, i;
if (font == NULL)
return FALSE;
Header = (uchar *)font + PreSkip;
if ( memcmp( font, "PK\x8\x8", 4)!=0 || *(Header++) != '+')
return FALSE;
for (i=0; i < 256; ++i) {
CH[i].width = 0;
CH[i].cmd = NULL;
}
nrch = *(short *)Header;
Header += 3;
fstch = *(Header++);
lastch = fstch + nrch;
cd = ((char *)font) + PreSkip + *(short *)Header;
Header += 3;
_height = *Header;
Header += 2;
_height -= *((schar *)Header);
cp = cd - nrch; /* -> width table */
sp = (short *) (cp - 2*nrch); /* -> offset table */
for (i=fstch; i < lastch; ++i)
CH[i].width = *(cp++);
for (i=fstch; i < lastch; ++i)
CH[i].cmd = (ushort *) (cd + sp[i-fstch]);
return TRUE;
}
static char *StdFonts[BOLD_FONT+1] = {
"", "TRIP.CHR", "LITT.CHR", "SANS.CHR", "GOTH.CHR", "SCRI.CHR",
"SIMP.CHR", "TSCR.CHR", "LCOM.CHR", "EURO.CHR", "BOLD.CHR" };
static int _registerfont( int start, int stop, void *font)
{
int i;
char *Header;
char *name;
do_init();
Header = (char *)font + PreSkip;
if ( memcmp( font, "PK\x8\x8",4)!=0 || *Header != '+')
return grInvalidFont;
name = (char *) font;
while (*name != '\x1a') {
if ( name-(char *)font > 128)
return grInvalidFont;
++name;
}
name += 3;
for (i=1; i <= BOLD_FONT; ++i)
if (memcmp( name, StdFonts[i], 4) == 0)
break;
if (i > BOLD_FONT) {
i = start;
while ( i <= stop && Fonts[i] != NULL)
++i;
if (i > stop)
return grNoFontMem;
}
Fonts[i] = font;
return i;
}
static int _installfont( int start, int stop, char *name)
{
FILE *ff;
long size;
void *font;
int res;
ff = fopen( name, "rb");
if (ff == NULL)
return grFileNotFound;
fseek( ff, 0, SEEK_END);
size = ftell(ff);
fseek( ff, 0, SEEK_SET);
font = malloc( (size_t) size);
if (font == NULL) {
fclose( ff);
return grNoFontMem;
}
fread( font, (size_t) size, 1, ff);
fclose( ff);
res = _registerfont(start, stop, font);
if (res < 0)
free( font);
return res;
}
int registerbgifont(void *font)
{
return _registerfont( FirstUserFont, LastUserFont, font);
}
int installuserfont(char *name)
{
char *loc_name;
loc_name = alloca(strlen(name)+1);
if (loc_name != NULL) {
strcpy(loc_name, name);
strlwr( loc_name);
if (strstr(loc_name, ".fnt") != 0)
return _installgrxfont( FirstGrxFont, LastGrxFont, name);
}
return _installfont( FirstUserFont, LastUserFont, name);
}
/* ----------------------------------------------------------------- */
int textheight(char *textstring)
{
_DO_INIT_CHECK_RV(0);
do_init();
if (TXT.font == DEFAULT_FONT)
return TXT.charsize * 8;
if (TXT.font >= FirstGrxFont && TXT.font <= LastGrxFont) {
gr_Text.txo_font = (GrFont *)Fonts[TXT.font];
gr_Text.txo_direct = GR_TEXT_RIGHT;
return GrStringHeight(textstring, strlen(textstring), &gr_Text);
}
return _height * _multy / _divy;
}
/* ----------------------------------------------------------------- */
int textwidth(char *textstring)
{
int sum;
_DO_INIT_CHECK_RV(0);
do_init();
if (TXT.font == DEFAULT_FONT)
return strlen(textstring) * TXT.charsize * 8;
if (TXT.font >= FirstGrxFont && TXT.font <= LastGrxFont) {
gr_Text.txo_font = (GrFont *)Fonts[TXT.font];
gr_Text.txo_direct = GR_TEXT_RIGHT;
return GrStringWidth(textstring, strlen(textstring), &gr_Text);
}
sum = 0;
while (*textstring != '\0')
sum += CH[*((uchar *)textstring++)].width * _multx / _divx;
return sum;
}
/* ----------------------------------------------------------------- */
inline static int xoff(ushort x)
{
x &= 0x7f;
if (x < 0x40) return x;
else return (int) ((signed char)(x | 0xc0));
}
inline static int yoff(ushort y)
{
return -xoff( y >> 8);
}
/* ----------------------------------------------------------------- */
static void _otxt_vec(int *xx, int *yy, int XX, int YY, uchar *textstring)
{
if (TXT.direction == HORIZ_DIR) {
int _XX, x, y, nx, ny, w;
ushort *dc;
switch (TXT.horiz) {
case CENTER_TEXT : XX -= textwidth(textstring) / 2; break;
case RIGHT_TEXT : XX -= textwidth(textstring); break;
default : break;
}
switch (TXT.vert) {
case CENTER_TEXT : YY += textheight(textstring) / 2; break;
case TOP_TEXT : YY += textheight(textstring); break;
default : break;
}
_XX = XX;
x = y = 0;
while (*textstring != '\0') {
w = CH[*textstring].width;
dc = CH[*(textstring++)].cmd;
while (dc != NULL) {
switch ( *dc & 0x8080) {
case 0x0000 : dc = NULL;
XX += w * _multx / _divx;
break;
case 0x8000 : /* ... */
++dc;
break;
case 0x0080 : x = xoff(*dc) * _multx / _divx;
y = yoff(*dc) * _multy / _divy;
++dc;
break;
case 0x8080 : nx = xoff(*dc) * _multx / _divx;
ny = yoff(*dc) * _multy / _divy;
GrLine( XX+x, YY+y, XX+nx, YY+ny, COL);
x = nx;
y = ny;
++dc;
break;
}
}
}
*xx += XX-_XX;
} else {
int _YY, x, y, nx, ny, w;
ushort *dc;
switch (TXT.horiz) {
case LEFT_TEXT : XX += textheight(textstring); break;
case CENTER_TEXT : XX += textheight(textstring) / 2; break;
default : break;
}
switch (TXT.vert) {
case CENTER_TEXT : YY += textwidth(textstring) / 2; break;
case TOP_TEXT : YY += textwidth(textstring); break;
default : break;
}
_YY = YY;
x = y = 0;
while (*textstring != '\0') {
w = CH[*textstring].width;
dc = CH[*(textstring++)].cmd;
while (dc != NULL) {
switch ( *dc & 0x8080) {
case 0x0000 : dc = NULL;
YY -= w * _multx / _divx;
break;
case 0x8000 : /* ... */
++dc;
break;
case 0x0080 : y = -xoff(*dc) * _multx / _divx;
x = yoff(*dc) * _multy / _divy;
++dc;
break;
case 0x8080 : ny = -xoff(*dc) * _multx / _divx;
nx = yoff(*dc) * _multy / _divy;
GrLine( XX+x, YY+y, XX+nx, YY+ny, COL);
x = nx;
y = ny;
++dc;
break;
}
}
}
*yy -= YY-_YY;
}
}
/* ----------------------------------------------------------------- */
static void _otxt_bit(int *xx, int *yy, int XX, int YY, uchar *txt)
{
int len;
gr_Text.txo_font = (GrFont *)Fonts[TXT.font];
gr_Text.txo_xmag =
gr_Text.txo_ymag = TXT.charsize;
gr_Text.txo_fgcolor.v = COL;
gr_Text.txo_bgcolor.v = GrNOCOLOR;
gr_Text.txo_direct = (TXT.direction == HORIZ_DIR) ? GR_TEXT_RIGHT:GR_TEXT_UP;
switch (TXT.horiz) {
case LEFT_TEXT : gr_Text.txo_xalign = GR_ALIGN_LEFT; break;
case RIGHT_TEXT : gr_Text.txo_xalign = GR_ALIGN_RIGHT; break;
case CENTER_TEXT :
default : gr_Text.txo_xalign = GR_ALIGN_CENTER; break;
}
switch (TXT.vert) {
case BOTTOM_TEXT : gr_Text.txo_yalign = GR_ALIGN_BOTTOM; break;
case TOP_TEXT : gr_Text.txo_yalign = GR_ALIGN_TOP; break;
case CENTER_TEXT :
default : gr_Text.txo_yalign = GR_ALIGN_CENTER; break;
}
len = strlen(txt);
GrDrawString( txt, len, XX, YY, &gr_Text);
if (TXT.direction == HORIZ_DIR)
*xx += GrStringWidth(txt, len, &gr_Text);
else {
gr_Text.txo_direct = GR_TEXT_RIGHT;
*yy -= GrStringWidth(txt,len, &gr_Text);
}
}
/* ----------------------------------------------------------------- */
static void _outtextxy(int *xx, int *yy, int XX, int YY, uchar *textstring)
{
_DO_INIT_CHECK;
do_init();
if (TXT.font==DEFAULT_FONT || (TXT.font>=FirstGrxFont && TXT.font<=LastGrxFont))
_otxt_bit(xx,yy,XX,YY,textstring);
else
_otxt_vec(xx,yy,XX,YY,textstring);
}
/* ----------------------------------------------------------------- */
void outtext( char *textstring)
{
_outtextxy(&X, &Y, X+VL, Y+VT, (uchar *)textstring);
}
/* ----------------------------------------------------------------- */
void outtextxy(int x, int y, char *textstring)
{
_outtextxy( &x, &y, x+VL, y+VT, (uchar *)textstring);
}
/* ----------------------------------------------------------------- */
void gettextsettings(struct textsettingstype *texttypeinfo)
{
_DO_INIT_CHECK;
do_init();
memcpy( texttypeinfo, &TXT, sizeof(TXT));
}
/* ----------------------------------------------------------------- */
void settextjustify(int horiz, int vert)
{
_DO_INIT_CHECK;
do_init();
TXT.horiz = horiz;
TXT.vert = vert;
}
/* ----------------------------------------------------------------- */
void settextstyle(int font, int direction, int charsize)
{
_DO_INIT_CHECK;
do_init();
if (font < DEFAULT_FONT || font >= NrFonts ||
(font > BOLD_FONT && Fonts[font] == NULL)) {
ERR = grInvalidFontNum;
return;
}
if (charsize < 0) charsize = 0;
if (charsize > 10) charsize = 10;
if (font != DEFAULT_FONT && (font<FirstGrxFont || font > LastGrxFont)) {
if (Fonts[font] == NULL) {
char fn[256], *cp;
strcpy(fn, (__gr_BGICHR != NULL ? __gr_BGICHR : ".\\"));
cp = fn;
while ( *cp != '\0') ++cp;
if ( *(--cp) != '\\') {
*(++cp) = '\\';
*(cp+1) = '\0';
}
strcat( fn, StdFonts[font]);
_installfont( font, font, fn);
}
if (!SetFont( Fonts[font]))
font = DEFAULT_FONT;
}
TXT.font = font;
TXT.direction = direction;
TXT.charsize = charsize;
_multx = _multy = _mult[charsize];
_divx = _divy = _div[charsize];
}
/* ----------------------------------------------------------------- */
void setusercharsize(int multx, int divx, int multy, int divy)
{
_DO_INIT_CHECK;
do_init();
if (divx == 0 || divy == 0 || TXT.font == DEFAULT_FONT) {
ERR = grError;
return;
}
TXT.charsize = 0;
_multx = multx;
_divx = divx;
_multy = multy;
_divy = divy;
}